package com.example.easycharge.notRepEntity;

import io.swagger.v3.oas.annotations.media.Schema;

import java.util.HashSet;
import java.util.LinkedList;

public class WaitArea {

    private final LinkedList<ChargeRequest> fastArea = new LinkedList<>();
    private final LinkedList<ChargeRequest> slowArea = new LinkedList<>();
    private final HashSet<Long> vehicleIdSet = new HashSet<>();
    private int areaSize;
    private final int MAX_AREA_SIZE = 10;
    // 经度范文
    private double longitudeMax;
    private double longitudeMIN;
    // 纬度范围
    private double latitudeMAX;
    private double latitudeMIN;

    public void addNewRequestToArea(ChargeRequest chargeRequest) {
        areaSize++;
        vehicleIdSet.add(chargeRequest.getVehicleId());
        if (chargeRequest.isFastCharge()) {
            fastArea.add(chargeRequest);
        } else {
            slowArea.add(chargeRequest);
        }
    }

    public ChargeRequest getNextRequest(boolean isFast) {
        if (isFast) {
            if (fastArea.size() != 0) {
                areaSize--;
                vehicleIdSet.remove(fastArea.peekFirst().getVehicleId());
                return fastArea.pollFirst();
            }
            return null;
        }
        if (slowArea.size() != 0) {
            areaSize--;
            vehicleIdSet.remove(slowArea.peekFirst().getVehicleId());
            return slowArea.pollFirst();
        }
        return null;
    }

    // 从等待队列中被挤出来的车辆，应该插到等候区的首位上
    public void insertRequest(ChargeRequest chargeRequest) {
        areaSize++;
        vehicleIdSet.add(chargeRequest.getVehicleId());
        if (chargeRequest.isFastCharge()) {
            fastArea.addFirst(chargeRequest);
        } else {
            slowArea.addFirst(chargeRequest);
        }
        // 如果插入车辆后让等候区超了，得移除一个末尾的车辆
        if (areaSize > MAX_AREA_SIZE) {
            if (fastArea.size() < 2) {
                slowArea.pollLast();
                return;
            }
            if (slowArea.size() < 2) {
                fastArea.pollLast();
                return;
            }
            // 其他情况下挑个最迟的踢出去
            ChargeRequest fastCharge = fastArea.peekLast();
            ChargeRequest slowCharge = slowArea.peekLast();
            if (fastCharge.getOrderNumber() > slowCharge.getOrderNumber()) {
                fastArea.pollLast();
            } else {
                slowArea.pollLast();
            }
        }
    }

    public ChargeRequest getRequestByVehicleId(long vehicleId) {
        for (ChargeRequest chargeRequest : fastArea) {
            if (chargeRequest.getVehicleId() == vehicleId) {
                return chargeRequest;
            }
        }
        for (ChargeRequest chargeRequest : slowArea) {
            if (chargeRequest.getVehicleId() == vehicleId) {
                return chargeRequest;
            }
        }
        return null;
    }

    public void moveToTail(long vehicleId, boolean isFast) {
        // 等候区中的车辆没有预计等待时间的概念
        ChargeRequest removedRequest = null;
        if (isFast) {
            for (ChargeRequest chargeRequest : fastArea) {
                if (chargeRequest.getVehicleId() == vehicleId) {
                    removedRequest = chargeRequest;
                    fastArea.remove(chargeRequest);
                    break;
                }
            }
        } else {
            for (ChargeRequest chargeRequest : slowArea) {
                if (chargeRequest.getVehicleId() == vehicleId) {
                    removedRequest = chargeRequest;
                    slowArea.remove(chargeRequest);
                    break;
                }
            }
        }
        if (removedRequest != null) {
            addNewRequestToArea(removedRequest);
        }
    }

    public int countAhead(long vehicleId) {
        int aheadCount = 0;

        for (ChargeRequest chargeRequest : fastArea) {
            if (chargeRequest.getVehicleId() == vehicleId) {
                break;
            }
            aheadCount++;
        }
        if (aheadCount != 0) {
            return aheadCount;
        }
        for (ChargeRequest chargeRequest : slowArea) {
            if (chargeRequest.getVehicleId() == vehicleId) {
                break;
            }
            aheadCount++;
        }
        return aheadCount;
    }

    public boolean existVehicle(long vehicleId) {
        return vehicleIdSet.contains(vehicleId);
    }

    public boolean cancelCharge(long vehicleId) {
        for (ChargeRequest chargeRequest : fastArea) {
            if (chargeRequest.getVehicleId() == vehicleId) {
                fastArea.remove(chargeRequest);
                vehicleIdSet.remove(chargeRequest.getVehicleId());
                areaSize--;
                return true;
            }
        }
        for (ChargeRequest chargeRequest : slowArea) {
            if (chargeRequest.getVehicleId() == vehicleId) {
                slowArea.remove(chargeRequest);
                vehicleIdSet.remove(chargeRequest.getVehicleId());
                areaSize--;
                return true;
            }
        }
        return false;
    }

    public boolean inArea(ChargeRequest chargeRequest) {
        double longitude = chargeRequest.getLongitude();
        double latitude = chargeRequest.getLatitude();
        if (longitude > longitudeMax || longitude < longitudeMIN) {
            return false;
        }
        return !(latitude > latitudeMAX) && !(latitude < latitudeMIN);
    }

    public int getAreaSize() {
        return areaSize;
    }

    public void clear(){
        fastArea.clear();
        slowArea.clear();
        vehicleIdSet.clear();
        areaSize=0;
    }

}
